package tournamentmanager;

public class SimulTournament extends AbstractTournament {

  private static final long serialVersionUID = -858007800308319023L;

  private ChessEngine simulEngine;

  private int cycles;

  private int currentCycle = 1;

  public SimulTournament(ChessEngine simulEngine) {
    this(simulEngine, new XboardMatchRunner());
  }

  public SimulTournament(ChessEngine simulEngine, MatchRunner matchRunner) {
    this.simulEngine = simulEngine;
    setMatchRunner(matchRunner);
  }

  public int getGamesToPlay() {
    if (simulEngine == null) {
      return 0;
    }
    return getPlayersList().size() * cycles;
  }

  public void run() {
    if (simulEngine != null) {
      int currentGameNum = 0;
      for (int cycleNum = 1; cycleNum <= cycles; cycleNum++) {
        currentCycle = cycleNum;
        for (ChessEngine engine : getPlayersList()) {
          currentGameNum++;
          if (getGamesPlayed() < currentGameNum) {
            runMatch(engine);
          }
        }
      }
    }
  }

  private void runMatch(ChessEngine engine) {
    MatchRunner match = getMatchRunner();
    match.setWhitePlayer(simulEngine);
    match.setBlackPlayer(engine);
    match.setTimeControl(getTimeControl());
    match.setSaveGameFile(getOutPGNFile());
    match.setMovesPerSession(getMovesPerSession());
    match.setTimeIncrement(getTimeIncrement());
    if (currentCycle % 2 == 0) {
      match.rotatePlayers();
    }
    runMatch();
  }

  public void setCycles(int cycles) {
    if (cycles < 1) {
      this.cycles = 1;
    } else {
      this.cycles = cycles;
    }
  }

  public int getCycles() {
    return cycles;
  }

  public void setSimulEngine(ChessEngine simulEngine) {
    this.simulEngine = simulEngine;
  }

  public ChessEngine getSimulEngine() {
    return simulEngine;
  }

  public void setCurrentCycle(int currentCycle) {
    this.currentCycle = currentCycle;
  }

  public int getCurrentCycle() {
    return currentCycle;
  }


  public void resetGames() {
    setGamesPlayed(0);
    setCurrentCycle(1);
  }
}
